home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 21 / Cream of the Crop 21 (Terry Blount) (October 1996).iso / os2 / e33el2.zip / emacs / 19.33 / lisp / sgml-mode.el < prev    next >
Lisp/Scheme  |  1996-07-02  |  42KB  |  1,261 lines

  1. ;;; sgml-mode.el --- SGML- and HTML-editing modes
  2.  
  3. ;; Copyright (C) 1992, 1995, 1996 Free Software Foundation, Inc.
  4.  
  5. ;; Author: James Clark <jjc@clark.com>
  6. ;; Adapted-By: ESR; Daniel.Pfeiffer@Informatik.START.dbp.de
  7. ;; Keywords: wp, hypermedia, comm, languages
  8.  
  9. ;; This file is part of GNU Emacs.
  10.  
  11. ;; GNU Emacs is free software; you can redistribute it and/or modify
  12. ;; it under the terms of the GNU General Public License as published by
  13. ;; the Free Software Foundation; either version 2, or (at your option)
  14. ;; any later version.
  15.  
  16. ;; GNU Emacs is distributed in the hope that it will be useful,
  17. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19. ;; GNU General Public License for more details.
  20.  
  21. ;; You should have received a copy of the GNU General Public License
  22. ;; along with GNU Emacs; see the file COPYING.  If not, write to the
  23. ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  24. ;; Boston, MA 02111-1307, USA.
  25.  
  26. ;;; Commentary:
  27.  
  28. ;; Configurable major mode for editing document in the SGML standard general
  29. ;; markup language.  As an example contains a mode for editing the derived
  30. ;; HTML hypertext markup language.
  31.  
  32. ;;; Code:
  33.  
  34. ;; As long as Emacs' syntax can't be complemented with predicates to context
  35. ;; sensitively confirm the syntax of characters, we have to live with this
  36. ;; kludgy kind of tradeoff.
  37. (defvar sgml-specials '(?\" ?-)
  38.   "List of characters that have a special meaning for sgml-mode.
  39. This list is used when first loading the sgml-mode library.
  40. The supported characters and potential disadvantages are:
  41.  
  42.   ?\\\"    Makes \" in text start a string.
  43.   ?'    Makes ' in text start a string.
  44.   ?-    Makes -- in text start a comment.
  45.  
  46. When only one of ?\\\" or ?' are included, \"'\" or '\"' as it can be found in
  47. DTDs, start a string.  To partially avoid this problem this also makes these
  48. self insert as named entities depending on `sgml-quick-keys'.  <!----> must
  49. contain an even multiple of two (4, 8, ...) minuses, or Emacs' syntax
  50. mechanism won't recognize a comment.")
  51.  
  52. (defvar sgml-quick-keys nil
  53.   "Use <, >, &, SPC and `sgml-specials' keys ``electrically'' when non-nil.
  54. This takes effect when first loading the library.")
  55.  
  56.  
  57. (defvar sgml-mode-map
  58.   (let ((map (list 'keymap (make-vector 256 nil)))
  59.     (menu-map (make-sparse-keymap "SGML")))
  60.     (define-key map "\t" 'indent-relative-maybe)
  61.     (define-key map "\C-c\C-i" 'sgml-tags-invisible)
  62.     (define-key map "/" 'sgml-slash)
  63.     (define-key map "\C-c\C-n" 'sgml-name-char)
  64.     (define-key map "\C-c\C-t" 'sgml-tag)
  65.     (define-key map "\C-c\C-a" 'sgml-attributes)
  66.     (define-key map "\C-c\C-b" 'sgml-skip-tag-backward)
  67.     (define-key map [?\C-c left] 'sgml-skip-tag-backward)
  68.     (define-key map "\C-c\C-f" 'sgml-skip-tag-forward)
  69.     (define-key map [?\C-c right] 'sgml-skip-tag-forward)
  70.     (define-key map "\C-c\C-d" 'sgml-delete-tag)
  71.     (define-key map "\C-c\^?" 'sgml-delete-tag)
  72.     (define-key map "\C-c?" 'sgml-tag-help)
  73.     (define-key map "\C-c8" 'sgml-name-8bit-mode)
  74.     (define-key map "\C-c\C-v" 'sgml-validate)
  75.     (if sgml-quick-keys
  76.     (progn
  77.       (define-key map "&" 'sgml-name-char)
  78.       (define-key map "<" 'sgml-tag)
  79.       (define-key map " " 'sgml-auto-attributes)
  80.       (define-key map ">" 'sgml-maybe-end-tag)
  81.       (if (memq ?\" sgml-specials)
  82.           (define-key map "\"" 'sgml-name-self))
  83.       (if (memq ?' sgml-specials)
  84.           (define-key map "'" 'sgml-name-self))))
  85.     (let ((c 127)
  86.       (map (nth 1 map)))
  87.       (while (< (setq c (1+ c)) 256)
  88.     (aset map c 'sgml-maybe-name-self)))
  89.     (define-key map [menu-bar sgml] (cons "SGML" menu-map))
  90.     (define-key menu-map [sgml-validate] '("Validate" . sgml-validate))
  91.     (define-key menu-map [sgml-name-8bit-mode]
  92.       '("Toggle 8 Bit Insertion" . sgml-name-8bit-mode))
  93.     (define-key menu-map [sgml-tags-invisible]
  94.       '("Toggle Tag Visibility" . sgml-tags-invisible))
  95.     (define-key menu-map [sgml-tag-help]
  96.       '("Describe Tag" . sgml-tag-help))
  97.     (define-key menu-map [sgml-delete-tag]
  98.       '("Delete Tag" . sgml-delete-tag))
  99.     (define-key menu-map [sgml-skip-tag-forward]
  100.       '("Forward Tag" . sgml-skip-tag-forward))
  101.     (define-key menu-map [sgml-skip-tag-backward]
  102.       '("Backward Tag" . sgml-skip-tag-backward))
  103.     (define-key menu-map [sgml-attributes]
  104.       '("Insert Attributes" . sgml-attributes))
  105.     (define-key menu-map [sgml-tag] '("Insert Tag" . sgml-tag))
  106.     map)
  107.   "Keymap for SGML mode.  See also `sgml-specials'.")
  108.  
  109.  
  110. (defvar sgml-mode-syntax-table
  111.   (let ((table (copy-syntax-table text-mode-syntax-table)))
  112.     (modify-syntax-entry ?< "(>" table)
  113.     (modify-syntax-entry ?> ")<" table)
  114.     (if (memq ?- sgml-specials)
  115.     (modify-syntax-entry ?- "_ 1234" table))
  116.     (if (memq ?\" sgml-specials)
  117.     (modify-syntax-entry ?\" "\"\"" table))
  118.     (if (memq ?' sgml-specials)
  119.     (modify-syntax-entry ?\' "\"'" table))
  120.     table)
  121.   "Syntax table used in SGML mode.  See also `sgml-specials'.")
  122.  
  123.  
  124. (defvar sgml-name-8bit-mode nil
  125.   "*When non-`nil' insert 8 bit characters with their names.")
  126.  
  127. (defvar sgml-char-names
  128.   [nil nil nil nil nil nil nil nil
  129.    nil nil nil nil nil nil nil nil
  130.    nil nil nil nil nil nil nil nil
  131.    nil nil nil nil nil nil nil nil
  132.    "ensp" "excl" "quot" "num" "dollar" "percnt" "amp" "apos"
  133.    "lpar" "rpar" "ast" "plus" "comma" "hyphen" "period" "sol"
  134.    nil nil nil nil nil nil nil nil
  135.    nil nil "colon" "semi" "lt" "eq" "gt" "quest"
  136.    "commat" nil nil nil nil nil nil nil
  137.    nil nil nil nil nil nil nil nil
  138.    nil nil nil nil nil nil nil nil
  139.    nil nil nil "lsqb" nil "rsqb" "uarr" "lowbar"
  140.    "lsquo" nil nil nil nil nil nil nil
  141.    nil nil nil nil nil nil nil nil
  142.    nil nil nil nil nil nil nil nil
  143.    nil nil nil "lcub" "verbar" "rcub" "tilde" nil
  144.    nil nil nil nil nil nil nil nil
  145.    nil nil nil nil nil nil nil nil
  146.    nil nil nil nil nil nil nil nil
  147.    nil nil nil nil nil nil nil nil
  148.    "nbsp" "iexcl" "cent" "pound" "curren" "yen" "brvbar" "sect"
  149.    "uml" "copy" "ordf" "laquo" "not" "shy" "reg" "macr"
  150.    "ring" "plusmn" "sup2" "sup3" "acute" "micro" "para" "middot"
  151.    "cedil" "sup1" "ordm" "raquo" "frac14" "half" "frac34" "iquest"
  152.    "Agrave" "Aacute" "Acirc" "Atilde" "Auml" "Aring" "AElig" "Ccedil"
  153.    "Egrave" "Eacute" "Ecirc" "Euml" "Igrave" "Iacute" "Icirc" "Iuml"
  154.    "ETH" "Ntilde" "Ograve" "Oacute" "Ocirc" "Otilde" "Ouml" nil
  155.    "Oslash" "Ugrave" "Uacute" "Ucirc" "Uuml" "Yacute" "THORN" "szlig"
  156.    "agrave" "aacute" "acirc" "atilde" "auml" "aring" "aelig" "ccedil"
  157.    "egrave" "eacute" "ecirc" "euml" "igrave" "iacute" "icirc" "iuml"
  158.    "eth" "ntilde" "ograve" "oacute" "ocirc" "otilde" "ouml" "divide"
  159.    "oslash" "ugrave" "uacute" "ucirc" "uuml" "yacute" "thorn" "yuml"]
  160.   "Vector of symbolic character names without `&' and `;'.")
  161.  
  162.  
  163. ;; sgmls is a free SGML parser available from
  164. ;; ftp.uu.net:pub/text-processing/sgml
  165. ;; Its error messages can be parsed by next-error.
  166. ;; The -s option suppresses output.
  167.  
  168. (defvar sgml-validate-command "sgmls -s"
  169.   "*The command to validate an SGML document.
  170. The file name of current buffer file name will be appended to this,
  171. separated by a space.")
  172.  
  173. (defvar sgml-saved-validate-command nil
  174.   "The command last used to validate in this buffer.")
  175.  
  176.  
  177. ;;; I doubt that null end tags are used much for large elements,
  178. ;;; so use a small distance here.
  179. (defconst sgml-slash-distance 1000
  180.   "*If non-nil, is the maximum distance to search for matching /.")
  181.  
  182. (defconst sgml-start-tag-regex
  183.   "<[A-Za-z]\\([-.A-Za-z0-9= \n\t]\\|\"[^\"]*\"\\|'[^']*'\\)*"
  184.   "Regular expression that matches a non-empty start tag.
  185. Any terminating > or / is not matched.")
  186.  
  187.  
  188. (defvar sgml-font-lock-keywords
  189.   '(("<\\([!?][a-z0-9]+\\)" 1 font-lock-keyword-face)
  190.     ("<\\(/?[a-z0-9]+\\)" 1 font-lock-function-name-face)
  191.     ("[&%][-.A-Za-z0-9]+;?" . font-lock-variable-name-face))
  192.   "*Rules for highlighting SGML code.  See also `sgml-tag-face-alist'.")
  193.  
  194. ;; internal
  195. (defvar sgml-font-lock-keywords-1 ())
  196.  
  197. (defvar sgml-face-tag-alist ()
  198.   "Alist of face and tag name for faceme